package com.ifacebox.client.tools;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import org.apache.commons.io.FilenameUtils;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.*;
import java.util.List;

/**
 * @author znn
 */
public class SspDiffSearchGui extends JFrame implements ActionListener {
    private static final String[] TABLE_COLUMN_NAME = new String[]{null, "编号", "名称", "地址"};
    private static final String STATUS_MESSAGE = "百度点位:%d 三川点位:%d 相同点位:%d 不同点位:%d";
    private static final Map<String, String[]> SSP_MAP = new HashMap<>();
    private static final List<List<String>> SSP_SAME_LIST = new ArrayList<>();
    private static final List<List<String>> SSP_DIFF_LIST = new ArrayList<>();
    private final JToolBar jToolBar;
    private JButton jButton1, jButton2, jButton3;
    private JCheckBox jCheckBox1, jCheckBox2;
    private JTable jTable1, jTable2;
    private DefaultTableModel tableModel1, tableModel2;
    private final JLabel jLabelStatus;
    private JFileChooser jFileChooser;

    public SspDiffSearchGui() {
        super.setTitle("百度聚屏三川点位差异搜索工具 - |编号|名称|地址|");
        super.setIconImage(new ImageIcon(SspConstants.LOGO_URL).getImage());
        super.setLayout(new BorderLayout());
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.add(jToolBar = new JToolBar() {{
            this.setLayout(new FlowLayout(FlowLayout.LEFT));
            this.add(jButton1 = new JButton("导入百度点位"));
            this.add(jButton2 = new JButton("导入三川点位"));
            this.add(jButton3 = new JButton("查找差异点位"));
            this.add(jCheckBox1 = new JCheckBox("名称", true));
            this.add(jCheckBox2 = new JCheckBox("地址", true));
        }}, BorderLayout.NORTH);
        super.add(new JPanel() {{
            this.setLayout(new GridLayout(0, 2, 5, 5));
            this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            this.add(new JPanel() {{
                this.setLayout(new BorderLayout());
                this.setBorder(BorderFactory.createTitledBorder("百度点位"));
                this.add(new JScrollPane(jTable1 = new JTable(tableModel1 = new DefaultTableModel(null, TABLE_COLUMN_NAME) {
                    @Override
                    public boolean isCellEditable(int row, int column) {
                        return false;
                    }
                })), BorderLayout.CENTER);
            }});
            this.add(new JPanel() {{
                this.setLayout(new BorderLayout());
                this.setBorder(BorderFactory.createTitledBorder("三川点位"));
                this.add(new JScrollPane(jTable2 = new JTable(tableModel2 = new DefaultTableModel(null, TABLE_COLUMN_NAME) {
                    @Override
                    public boolean isCellEditable(int row, int column) {
                        return false;
                    }
                })), BorderLayout.CENTER);
            }});
        }}, BorderLayout.CENTER);
        super.add(jLabelStatus = new JLabel(String.format(STATUS_MESSAGE, 0, 0, 0, 0)) {{
            this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        }}, BorderLayout.SOUTH);
        this.initComponents();
        super.pack();
        super.setLocationRelativeTo(null);
    }

    public void initComponents() {
        jFileChooser = new JFileChooser();
        jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        jFileChooser.setAcceptAllFileFilterUsed(false);
        jFileChooser.addChoosableFileFilter(new FileNameExtensionFilter(SspConstants.EXCEL_EXTENSION_DESCRIPTION, SspConstants.EXCEL_EXTENSION));
        jButton1.addActionListener(this);
        jButton2.addActionListener(this);
        jButton3.addActionListener(this);
        jTable1.setRowHeight(30);
        jTable1.getColumnModel().getColumn(0).setMinWidth(0);
        jTable1.getColumnModel().getColumn(0).setMaxWidth(0);
        jTable1.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value
                    , boolean isSelected, boolean hasFocus, int row, int column) {
                Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                Object obj = tableModel1.getValueAt(row, 0);
                comp.setBackground(obj == null ? Color.WHITE : (boolean) obj ? Color.GREEN : Color.RED);
                comp.setForeground(Color.BLACK);
                return comp;
            }
        });
        jTable2.setRowHeight(30);
        jTable2.getColumnModel().getColumn(0).setMinWidth(0);
        jTable2.getColumnModel().getColumn(0).setMaxWidth(0);
        jTable2.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value
                    , boolean isSelected, boolean hasFocus, int row, int column) {
                Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                comp.setBackground(Color.WHITE);
                comp.setForeground(Color.BLACK);
                return comp;
            }
        });
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == jButton1) {
            Arrays.stream(jToolBar.getComponents()).forEach(comp -> comp.setEnabled(false));
            SspUtils.runThread(() -> {
                try {
                    if (JFileChooser.APPROVE_OPTION == jFileChooser.showOpenDialog(this)) {
                        if (SspUtils.isExcel(jFileChooser.getSelectedFile())) {
                            if (tableModel1.getRowCount() > 0 && JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this
                                    , "是否清空百度点位？", super.getTitle(), JOptionPane.YES_NO_OPTION)) {
                                tableModel1.setRowCount(0);
                            }
                            this.addTableModel(jFileChooser.getSelectedFile(), tableModel1, null);
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this
                            , ex.toString(), super.getTitle(), JOptionPane.ERROR_MESSAGE);
                } finally {
                    Arrays.stream(jToolBar.getComponents()).forEach(comp -> comp.setEnabled(true));
                }
            }, "");
        }
        if (e.getSource() == jButton2) {
            Arrays.stream(jToolBar.getComponents()).forEach(comp -> comp.setEnabled(false));
            SspUtils.runThread(() -> {
                try {
                    if (JFileChooser.APPROVE_OPTION == jFileChooser.showOpenDialog(this)) {
                        if (SspUtils.isExcel(jFileChooser.getSelectedFile())) {
                            if (tableModel2.getRowCount() > 0 && JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this
                                    , "是否清空三川点位？", super.getTitle(), JOptionPane.YES_NO_OPTION)) {
                                SSP_MAP.clear();
                                tableModel2.setRowCount(0);
                            }
                            this.addTableModel(jFileChooser.getSelectedFile(), tableModel2, SSP_MAP);
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this
                            , ex.toString(), super.getTitle(), JOptionPane.ERROR_MESSAGE);
                } finally {
                    Arrays.stream(jToolBar.getComponents()).forEach(comp -> comp.setEnabled(true));
                }
            }, "");
        }
        if (e.getSource() == jButton3) {
            Arrays.stream(jToolBar.getComponents()).forEach(comp -> comp.setEnabled(false));
            SspUtils.runThread(() -> {
                try {
                    this.diffSearch();
                    if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this
                            , "查找完成，是否保存查找结果？", super.getTitle(), JOptionPane.YES_NO_OPTION)) {
                        if (JFileChooser.APPROVE_OPTION == jFileChooser.showSaveDialog(this)) {
                            if (jFileChooser.getSelectedFile().exists()
                                    && JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(this
                                    , "文件存在，是否覆盖文件？", super.getTitle(), JOptionPane.YES_NO_OPTION)) {
                                return;
                            }
                            File file = this.diffImport(jFileChooser.getSelectedFile());
                            if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this
                                    , "保存完成，是否打开查找结果？", super.getTitle(), JOptionPane.YES_NO_OPTION)) {
                                Desktop.getDesktop().open(file);
                            }
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this, ex.toString(), super.getTitle(), JOptionPane.ERROR_MESSAGE);
                } finally {
                    Arrays.stream(jToolBar.getComponents()).forEach(comp -> comp.setEnabled(true));
                }
            }, "");
        }
    }

    public File diffImport(File file) {
        if (!Arrays.asList(SspConstants.EXCEL_EXTENSION).contains(FilenameUtils.getExtension(file.getName()))) {
            file = new File(file.getParentFile(), String.format("%s.%s", FilenameUtils.getBaseName(file.getName()), SspConstants.XLS));
        }
        ExcelWriter excelWriter = EasyExcel.write(file).head(new ArrayList<List<String>>() {{
            Arrays.stream(TABLE_COLUMN_NAME).filter(Objects::nonNull).forEach(s -> this.add(Collections.singletonList(s)));
        }}).build();
        excelWriter.write(SSP_SAME_LIST, EasyExcel.writerSheet().sheetName("相同点位").build());
        excelWriter.write(SSP_DIFF_LIST, EasyExcel.writerSheet().sheetName("不同点位").build());
        excelWriter.finish();
        return file;
    }

    public void diffSearch() {
        SSP_SAME_LIST.clear();
        SSP_DIFF_LIST.clear();
        for (int i = 0; i < tableModel1.getRowCount(); i++) {
            tableModel1.setValueAt(null, i, 0);
            Object obj1 = tableModel1.getValueAt(i, 1);
            Object obj2 = tableModel1.getValueAt(i, 2);
            Object obj3 = tableModel1.getValueAt(i, 3);
            String s1 = obj1 == null ? "" : obj1.toString().trim();
            String s2 = obj2 == null ? "" : obj2.toString().trim();
            String s3 = obj3 == null ? "" : obj3.toString().trim();
            if (SSP_MAP.containsKey(s1)) {
                String[] obj = SSP_MAP.get(s1);
                if (jCheckBox1.isSelected() && jCheckBox2.isSelected()) {
                    if (s2.equalsIgnoreCase(obj[2]) && s3.equalsIgnoreCase(obj[3])) {
                        SSP_SAME_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                        tableModel1.setValueAt(true, i, 0);
                    } else {
                        SSP_DIFF_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                        tableModel1.setValueAt(false, i, 0);
                    }
                } else if (jCheckBox1.isSelected()) {
                    if (s2.equalsIgnoreCase(obj[2])) {
                        SSP_SAME_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                        tableModel1.setValueAt(true, i, 0);
                    } else {
                        SSP_DIFF_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                        tableModel1.setValueAt(false, i, 0);
                    }
                } else if (jCheckBox2.isSelected()) {
                    if (s3.equalsIgnoreCase(obj[3])) {
                        SSP_SAME_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                        tableModel1.setValueAt(true, i, 0);
                    } else {
                        SSP_DIFF_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                        tableModel1.setValueAt(false, i, 0);
                    }
                } else {
                    tableModel1.setValueAt(true, i, 0);
                    SSP_SAME_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
                }
            } else {
                tableModel1.setValueAt(false, i, 0);
                SSP_DIFF_LIST.add(new ArrayList<>(Arrays.asList(s1, s2, s3)));
            }
        }
        jLabelStatus.setText(String.format(STATUS_MESSAGE
                , tableModel1.getRowCount(), tableModel2.getRowCount(), SSP_SAME_LIST.size(), SSP_DIFF_LIST.size()));
        jTable1.updateUI();
    }

    public void addTableModel(File file, DefaultTableModel tableModel, Map<String, String[]> sspMap) {
        EasyExcel.read(file, new ReadListener<Map<Integer, String>>() {
            @Override
            public void invoke(Map<Integer, String> map, AnalysisContext analysisContext) {
                SwingUtilities.invokeLater(() -> {
                    String s1 = map.get(0) == null ? "" : map.get(0).trim();
                    String s2 = map.get(1) == null ? "" : map.get(1).trim();
                    String s3 = map.get(2) == null ? "" : map.get(2).trim();
                    tableModel.addRow(new Object[]{null, s1, s2, s3});
                    if (sspMap != null) {
                        sspMap.put(s1, new String[]{null, s1, s2, s3});
                    }
                    jLabelStatus.setText(String.format(STATUS_MESSAGE
                            , tableModel1.getRowCount(), tableModel2.getRowCount(), SSP_SAME_LIST.size(), SSP_DIFF_LIST.size()));
                });
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                jLabelStatus.setText(String.format(STATUS_MESSAGE
                        , tableModel1.getRowCount(), tableModel2.getRowCount(), SSP_SAME_LIST.size(), SSP_DIFF_LIST.size()));
            }
        }).sheet().doRead();
    }

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        new SspDiffSearchGui().setVisible(true);
        System.out.println((byte) Integer.parseInt("50", 16));
    }


}
